home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / blix / blix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  25.3 KB  |  1,073 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*__________________________________________________________________________
  18.  |
  19.  | blix.c - the main part of the blix program
  20.  |
  21.  |
  22.  |     (c) 1993 Frans van Hoesel, Xtreme graphics software
  23.  |    hoesel@chem.rug.nl
  24. */
  25.  
  26.  
  27.  
  28. #include <alloca.h>
  29. #include <math.h>
  30. #include <gl/gl.h>
  31. #include <gl/device.h>
  32. #include <gl/get.h>
  33. #include <gl/sphere.h>
  34. #include <gl/image.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <unistd.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <fcntl.h>
  42.  
  43. #include "blix.h"
  44. #include "blixfont.h"
  45. #include "blixscore.h"
  46. #include "blixsound.h"
  47. #include "blixmenu.h"
  48. #include "blixui.h"
  49. #include "blixtexture.h"
  50. #include "bliximage.h"
  51. #include "blixscore_io.h"
  52. #include "config.h"
  53. #include "lod.h"
  54. #include "maze.h"
  55. #include "mymath.h"
  56. #include "players.h"
  57. #include "transparent.h"
  58. #include "IvtoGL.h"
  59.  
  60. int Lod = 2;
  61. int can_do_textures = 0;
  62. int notune = 0;
  63. int noworld = 0;
  64.  
  65. static float spinrot[4] = {0.0, 0.0, 0.0, 1.0};
  66. static float rvec[4] ; /* initialized in reset_transforms */
  67. static float trans[3];
  68. static int report_nodenum = FALSE;
  69. static int displmode;
  70. static int saved_displmode;
  71. static int zbuf = TRUE;
  72. static float mouse_clicked[3];
  73. static float y_pos;
  74. userinfo_t *inf;
  75. long zmin, zmax;
  76.  
  77. extern node_t *the_nodes;
  78. extern float trackpoint[3];
  79. extern float trackballsize;
  80. extern int mouse_dead;
  81.  
  82. float tb_project_to_sphere(const float r, const float x, const float y);
  83. int node_closest(float v[3], int nodenum, float mindist);
  84. int sginap(long);
  85.  
  86. void remember_view(float *, float *);
  87. void spin_draw(void);
  88. void do_menus(void);
  89. void draw_whatever(void);
  90. void set_perspective(void);
  91. void init_windows(void) ;
  92. void init_menus(void) ;
  93. void init_path(void) ;
  94. void build_matrix(void);
  95. void reset_rot(void);
  96.  
  97. /* from imagelib: */
  98. IMAGE *iopen();
  99. void getrow(IMAGE *, short *, int , int);
  100. void iclose(IMAGE *);
  101.  
  102. static float sphere_material[] = {
  103.             DIFFUSE, 0.795918, 0.273554, 0.00686136,
  104.             AMBIENT, 0.0, 0.0, 0.0,
  105.             SPECULAR, 0.48655, 0.319155, 0.444036,
  106.             SHININESS, 86,
  107.             EMISSION,  0.208082, 0.070142, 0.00175932,
  108.             ALPHA, 0.0,
  109.             LMNULL };
  110. static float sphere_material2[] = {
  111.             DIFFUSE, 0.495918, 0.053554, 0.00286136,
  112.             AMBIENT, 0.0, 0.0, 0.0,
  113.             SPECULAR, 0.48655, 0.319155, 0.444036,
  114.             SHININESS, 86,
  115.             EMISSION,  0.20, 0.030142, 0.00055932,
  116.             ALPHA, 0.0,
  117.             LMNULL };
  118. static float wall_material[] = {
  119.             DIFFUSE, 0.53, 0.14, 0.0039,
  120.             AMBIENT, 0, 0, 0,
  121.             EMISSION, 0.2, 0.14, 0.0017,
  122.             SPECULAR, 1, 0.991559, 0.963793,
  123.             SHININESS, 66,
  124.             ALPHA, 0.0,
  125.             LMNULL };
  126. static float darkwall_material[] = {
  127.             DIFFUSE, 0.53, 0.14, 0.0039,
  128.             AMBIENT, 0, 0, 0,
  129.             EMISSION, 0.2, 0.14, 0.0017,
  130.             SPECULAR, 0.1, 0.0991559, 0.0963793,
  131.             SHININESS, 66,
  132.             ALPHA, 0.0,
  133.             LMNULL };
  134. static float topwall_material[] = {
  135.             DIFFUSE, 0.14, 0.06, 0.31,
  136.             AMBIENT, 0, 0, 0,
  137.             EMISSION, 0.2, 0.14, 0.0017,
  138.             SPECULAR, 0.1, 0.0991559, 0.0963793,
  139.             SHININESS, 66,
  140.             ALPHA, 0.0,
  141.             LMNULL };
  142.  
  143. static float light1[] = {
  144.             POSITION, -1.0, 2.0, 1.0, 0.0,
  145.             LMNULL } ;
  146. static float light2[] = {
  147.             POSITION, 1.0, 2.0, -1.0, 0.0,
  148.             LCOLOR, 0.7, 1.0, 1.0,
  149.             AMBIENT, -0.2, -0.2, -0.2,
  150.             LMNULL } ;
  151. static float light3[] = {
  152.             POSITION, 0, 0.75, 0.0,
  153.             LMNULL };
  154.  
  155. static float light4[] = {
  156.             POSITION, 1.0, -2.0, 1.0, 0.0,
  157.             LMNULL } ;
  158. static float light0[] = {
  159.             LMNULL } ;
  160. static float lmodel[] = {
  161.             AMBIENT, 0.1, 0.1, 0.1,
  162.             LMNULL } ;
  163. static float lmodel0[] = {
  164.             LMNULL } ;
  165. static float material0[] = {
  166.             LMNULL } ;
  167. static float sphere[4] = { 0,0,0, 0.999};
  168.  
  169. Matrix rotmat;
  170. Matrix invrotmat;
  171. char *basename;
  172. char *datadir;
  173. int no_sfx = 1;
  174. int playing_tune = 0;
  175. int current_tune = 0;
  176. int display_scene = 1;
  177.  
  178.  
  179. /*__________________________________________________________________
  180.  |
  181.  | main 
  182. */
  183.  
  184. int main(int argc, char *argv[]) {
  185.     
  186.     char *m;
  187.     /* keep basename, for error messages */
  188.     basename = strdup( argv[0]);
  189.     if (strrchr(basename,'/') != NULL) {
  190.     basename = strrchr(basename,'/')+1;
  191.     }
  192.     if (argc >= 2) {
  193.     if (strcmp (argv[1],"-s") == NULL ||
  194.         strcmp(argv[argc-1], "-s") == NULL) {
  195.         notune = 1;
  196.     }
  197.     if (strcmp(argv[1], "-w") == NULL ||
  198.         strcmp(argv[argc-1], "-w") == NULL) {
  199.         noworld = 1;
  200.     }
  201.     }
  202.     init_path();
  203.     display_scene = INTRO;
  204.     init_tmpdir();
  205.     init_windows();
  206.     init_ui();
  207.     init_fonts();
  208.     draw_whatever2d();
  209.     no_sfx = init_sound();
  210.     current_tune = SFX_TUNE_A;
  211.     if (notune) {
  212.     toggle_tune();
  213.     toggle_tune();
  214.     } else {
  215.     /* the sleep makes things work as they should,
  216.      */
  217.     sleep(1);
  218.     sfx(SFX_WELCOME);
  219.     sleep(2);
  220.     toggle_tune();
  221.     playing_tune = 1;
  222.     sfx(current_tune);
  223.     }
  224.     init_server();
  225.     init_alpha();
  226.     init_maze();
  227.     init_menus();
  228.     init_players();
  229.     init_textures();
  230.     /* final brutal check for memory if this fails, then probably one of
  231.      * the unchecked mallocs failed too
  232.      */
  233.     m = (char *) malloc(200000);
  234.     if (m == NULL) {
  235.     fprintf(stderr, "%s: Not Enough Memory\n", basename);
  236.     exit_program();
  237.     }
  238.     free(m);
  239.     doscore(0);
  240.     gflush();
  241.     reset_transforms();
  242.     backface(TRUE);
  243.     lmdef(DEFMATERIAL, 1, sizeof(sphere_material), sphere_material);
  244.     lmdef(DEFMATERIAL, 2, sizeof(wall_material), wall_material);
  245.     lmdef(DEFMATERIAL, 3, sizeof(darkwall_material), darkwall_material);
  246.     lmdef(DEFMATERIAL, 4, sizeof(topwall_material), topwall_material);
  247.     lmdef(DEFMATERIAL, 5, sizeof(sphere_material2), sphere_material2);
  248.     lmdef(DEFMATERIAL, 10, sizeof(material0), material0);
  249.     lmdef(DEFLMODEL, 1, sizeof(lmodel), lmodel);
  250.     lmdef(DEFLMODEL, 10, sizeof(lmodel0), lmodel0);
  251.     lmdef(DEFLIGHT, 1, sizeof(light1), light1);
  252.     lmdef(DEFLIGHT, 2, sizeof(light2), light2);
  253.     lmdef(DEFLIGHT, 3, sizeof(light3), light3);
  254.     lmdef(DEFLIGHT, 4, sizeof(light4), light4);
  255.     lmdef(DEFLIGHT, 10, sizeof(light0), light0);
  256.     lmbind(LMODEL, 1);
  257.     lmbind(LIGHT0, 1);
  258.     if (Lod >= EXTRA_LIGHT )
  259.     lmbind(LIGHT1,2);
  260.     sphmode(SPH_TESS, SPH_OCT);
  261.     sphmode(SPH_HEMI, TRUE);
  262.     /* the next line may seem strange for speedy spheres
  263.      * but it saves a few micro seconds, because the matrix
  264.      * at the time of calling sphdraw, is always oriented
  265.      */
  266.     sphmode(SPH_ORIENT, FALSE);
  267.     sphmode(SPH_PRIM, SPH_MESH);
  268.     if (Lod >= EXTRA_FINE)
  269.     sphmode(SPH_DEPTH, 12);
  270.     else
  271.     sphmode(SPH_DEPTH, 11);
  272.     shademodel(GOURAUD);
  273.     build_maze(0, Lod);
  274.     reshapeviewport();
  275.     zbuffer(zbuf);
  276.     display_scene = GAME;
  277.     draw_whatever();
  278.     uimode = MODE3D;
  279.     start_full_menu();
  280.     ui();
  281.     exit_program();
  282.     return 0;
  283. }
  284.  
  285. void exit_program(void) {
  286.     tune_off();
  287.     sleep(1);
  288.     end_sound();
  289.     sginap(CLK_TCK/4);
  290.     gexit();
  291.     exit (0);
  292. }
  293.  
  294. /*___________________________________________________________________
  295.  | 
  296.  | init_path - find the path leading to the directory with blix data.
  297.  |
  298.  | the path to all the data files for blix is determined only once,
  299.  | by searching for the file blix.dat. (this file is used for nothing
  300.  | else; forget about its cryptic contents it's just a joke)
  301.  | specific testing is done for Indyzone path, and relative path
  302.  | on the developers CD, also DATADIR (defined at compile time),
  303.  | the current directory and the environment variable BLIXDIR are
  304.  | checked.
  305.  |
  306. */
  307.  
  308. void init_path(void) {
  309.     int f;
  310.     char fullpath[512];
  311.     
  312.     f = -1;
  313.     datadir = getenv("BLIXDIR");
  314.     if (datadir != NULL) {
  315.     strcpy(fullpath, datadir);
  316.     strcat(fullpath, "/blix.dat");
  317.     f = open(fullpath, O_RDONLY);
  318.     }
  319. #ifdef DATADIR 
  320.     if (f == -1) {
  321.     strcpy(fullpath, DATADIR);
  322.     strcat(fullpath, "/blix.dat");
  323.     f = open(fullpath, O_RDONLY);
  324.     }
  325. #endif
  326.     if (f == -1) {
  327.     strcpy(fullpath, "/usr/demos/IndiZone/.data/blix/blix.dat");
  328.     f = open(fullpath, O_RDONLY);
  329.     }
  330.     if (f == -1) {
  331.     strcpy(fullpath, "../data/blix/blix.dat");
  332.     f = open(fullpath, O_RDONLY);
  333.     }
  334.     if (f == -1) {
  335.     strcpy(fullpath, "./blix.dat");
  336.     f = open(fullpath, O_RDONLY);
  337.     }
  338.     if (f == -1) {
  339.     fprintf(stderr,"%s: unable to find blix.dat needed for running"
  340.         " blix.\n", basename);
  341.     exit(1);
  342.     }
  343.     close(f);
  344.     datadir = strdup(fullpath);
  345.     /* strip off the blix.dat part */
  346.     *(strrchr(datadir, '/')+1) = '\0';
  347. }
  348.  
  349. /*_________________________________________________________________
  350.  |
  351.  | remember_view -  is called from the ui routine.
  352.  |
  353.  | in t[0] I encode the operation to be done (pan/zoom); the
  354.  | parameters of the operation are in t[1] and t[2].
  355.  |
  356. */
  357.  
  358. void remember_view(float *r, float *t) {
  359.  
  360.     int nodenum;
  361.     
  362.     /* first time, switch to double buffered mode */
  363.     if (displmode == DMRGB) {
  364.     sfx(SFX_BEEP);
  365.     cpack(0x00000000);
  366.     clear();
  367.     gflush();
  368.     displmode = DMRGBDOUBLE;
  369.     doublebuffer();
  370.     gconfig();
  371.     gflush();
  372.     cpack(0x0000000);
  373.     if (zbuf) {
  374.         czclear(0x00000000, zmax);
  375.         swapbuffers();
  376.         czclear(0x00000000, zmax);
  377.         
  378.     } else {
  379.         clear();
  380.         swapbuffers();
  381.         clear();
  382.     }
  383.     }
  384.     /* t is an array of three floats, the first holds the 'command'
  385.      * the other two, the parameters; silly, but compatible.
  386.      */
  387.     if (t[0] == 0) {
  388.     /* 'pan' */
  389.     /* not really panning, just record the mouse position, and use
  390.      * that to guide blix around the maze.
  391.      */
  392.     mouse_clicked[0] = t[1];
  393.     mouse_clicked[1] = t[2];
  394.     trackpoint[0] = t[1];
  395.     trackpoint[1] = t[2] - y_pos;
  396.     trackpoint[2] = tb_project_to_sphere(trackballsize*1.005,
  397.         trackpoint[0], trackpoint[1]);
  398.     vtransform(trackpoint, invrotmat, trackpoint);
  399.     vnormal(trackpoint);
  400.     if (report_nodenum) {
  401.         nodenum = node_closest(trackpoint, -1, 0.0001);
  402.         if (nodenum >= 0) {
  403.         fprintf(stderr,"node %d: %f %f %f distance %f\n", nodenum, 
  404.             the_nodes[nodenum].pos[0],
  405.             the_nodes[nodenum].pos[1],
  406.             the_nodes[nodenum].pos[2],
  407.             vdistance(the_nodes[nodenum].pos, trackpoint));
  408.         }
  409.     }
  410.     add_quats(spinrot, rvec, rvec);
  411.     build_matrix();
  412.     } else if (t[0] == 1) {
  413.     /* zoom */
  414.     trans[2] += t[2]*6;
  415.     if (trans[2] > -1.1* SCALE)
  416.         trans[2] = -1.1 * SCALE;
  417.     trans[0] = 0;
  418.     /* zoom not only zooms in, but also translates a bit, so you
  419.      * don't zoom in via a straight line to the center, but via
  420.      * an exponential line towards a point above the pole
  421.      */
  422.     trans[1] = -1.8*exp(trans[2]/14)+0.662;        
  423.     if (trans[1] > 0) trans[1] = 0;
  424.     set_perspective();
  425.     spinrot[0] = 0;
  426.     spinrot[1] = 0;
  427.     spinrot[2] = 0;
  428.     spinrot[3] = 1;
  429.     } else if (t[0] == 2) {
  430.     /* Remember the rotation so we can spin... */
  431.     spinrot[0] = r[0];
  432.     spinrot[1] = r[1];
  433.     spinrot[2] = r[2];
  434.     spinrot[3] = r[3];
  435.     add_quats(r, rvec, rvec);    /* And add on more rotation */
  436.     build_matrix();
  437.     }
  438.     draw_whatever();    /* And draw the scene */
  439. }
  440.  
  441.  
  442. /*__________________________________________________________________
  443.  |
  444.  | switch_single - switch to single buffer RGB mode
  445.  |
  446.  | set the color to some color that looks appr. the same in both buffer
  447.  | modes, like cpack(0x00332244), or simply black or white.
  448.  | But set that color before you call this routine.
  449.  |
  450. */
  451.  
  452. void switch_single(void) {
  453.  
  454.     if (displmode == DMRGBDOUBLE ) {
  455.     displmode = DMRGB;
  456.     frontbuffer(TRUE);
  457.     clear();
  458.     frontbuffer(FALSE);
  459.     gflush();
  460.     singlebuffer();
  461.     gconfig();
  462.     }
  463.     
  464. }
  465.  
  466. /*___________________________________________________________________
  467.  |
  468.  | switch_double - switch to double buffer RGB mode
  469.  |
  470. */
  471.  
  472. void switch_double(void) {
  473.     
  474.     cpack(0x0000000);
  475.     if (displmode == DMRGB) {
  476.     clear();
  477.     gflush();
  478.     displmode = DMRGBDOUBLE;
  479.     doublebuffer();
  480.     gconfig();
  481.     gflush();
  482.     }
  483.     clear();
  484. }
  485.  
  486. /*__________________________________________________________________
  487.  |
  488.  | save_displaymode - save current display mode
  489.  |
  490. */
  491.  
  492. void save_displaymode(void) {
  493.     saved_displmode = displmode;
  494. }
  495.  
  496. /*__________________________________________________________________
  497.  |
  498.  | restore_displaymode - restore mode from saved state
  499.  |
  500. */
  501.  
  502. void restore_displaymode(void) {
  503.     if (displmode != saved_displmode) {
  504.     switch (saved_displmode) {
  505.       case DMRGBDOUBLE:
  506.         switch_double();
  507.         break;
  508.       case DMRGB:
  509.         switch_single();
  510.         break;
  511.     }
  512.     }
  513.  
  514.  
  515. /*__________________________________________________________________
  516.  |
  517.  | spin_draw - draw spinning world
  518.  |
  519. */
  520.  
  521. void spin_draw(void) {
  522.     /*
  523.      *    The ui_quiet flag is defined in "ui.h", and is
  524.      * kept up-to-date by the ui() routines.  When
  525.      * ui_quiet is FALSE, leave the object alone to let the
  526.      * user interact with it.
  527.      */
  528.     if (ui_quiet) {
  529.     if (displmode == DMRGB) {
  530.         sfx(SFX_BEEP);
  531.         cpack(0x00000000);
  532.         clear();
  533.         gflush();
  534.         displmode = DMRGBDOUBLE;
  535.         doublebuffer();
  536.         gconfig();
  537.         gflush();
  538.         cpack(0x0000000);
  539.         if (zbuf) {
  540.         czclear(0x00000000, zmax);
  541.         swapbuffers();
  542.         czclear(0x00000000, zmax);
  543.         
  544.         } else {
  545.         clear();
  546.         swapbuffers();
  547.         clear();
  548.         }
  549.     }
  550.         if (spinrot[0] != 0 || spinrot[1] != 0 || spinrot[2] != 0 
  551.         || spinrot[3] != 1) {
  552.         add_quats(spinrot, rvec, rvec); /* rotate again */
  553.         build_matrix();
  554.     }
  555.     draw_whatever();    /* And draw the scene */
  556.     }
  557. }
  558.  
  559.  
  560. extern int score;
  561. extern int highscore;
  562.  
  563. /* ARGSUSED */
  564. void draw_whatever(void) {
  565.     float val;
  566.     char *c;
  567.     char st[20];
  568.     float x, alph;
  569.     
  570.     zbuffer(zbuf);
  571.     switch (display_scene) {
  572.       case GAME:
  573.     pushmatrix();
  574.     if (mouse_dead) { 
  575.         sphere[3]+=0.008;
  576.         mouse_dead++;
  577.         if (sphere[3] > 1.2 && mouse_dead>60) {
  578.         sphere[3] = 0.999;
  579.         sleep(1);
  580.         mouse_dead = 0;
  581.         doscore(score);
  582.         score = 0;
  583.         switch_double();
  584.         zbuffer(zbuf);
  585.         reset_rot();
  586.         }
  587.     }
  588.     val = trans[2]*SCALE*TANFOVY;
  589.     ortho(val, -val, val, -val, NEAR, -trans[2] + EXTRA);
  590.     y_pos = trans[1]/(-val);
  591.     cpack(0x00000000);
  592.     if (zbuf) {
  593.         czclear(0x00000000, zmax);
  594.     } else {
  595.         clear();
  596.     }
  597.     translate(trans[0], trans[1], trans[2]);
  598.     players_action();
  599.     
  600.     if (Lod >= TEXTURE_MAPS && can_do_textures) {
  601.         lmbind(MATERIAL, 5);
  602.     } else {
  603.         lmbind(MATERIAL,1);
  604.     }
  605.     lmbind(LIGHT0,1);
  606.     sphdraw(sphere);
  607.     draw_maze(rotmat, zbuf);
  608.     draw_players(rotmat, invrotmat);
  609.     
  610.     popmatrix();
  611.     pushmatrix();
  612.     zbuffer(FALSE);
  613.     ortho2(-1,1, -1, 1);
  614.     if (mouse_dead > 5) {
  615.         /* draw a black square, but with appropiate alpha, so
  616.          * it the scene slowly fades away
  617.          */
  618.         alph = 1.0-(mouse_dead-5)/24.0;
  619.         if (alph < 0 ) {
  620.         alph = 0;
  621.         } else if (alph > 1.0) {
  622.         alph = 1.0;
  623.         }
  624.         set_alpha(alph);
  625.         cpack(0x00000000);
  626.         rectfi(-1, -1, 1, 1);
  627.         set_alpha(0);
  628.     }
  629.     sprintf(st, "%d",score);
  630.     c = st; 
  631.     x = -0.8;
  632.     while (*c) {
  633.         pushmatrix();
  634.         translate(x, -0.9, 0);
  635.         callobj(8000 + *c - '0');
  636.         popmatrix();
  637.         x+= 0.05;
  638.         c++;
  639.     }
  640.     if (highscore != 0) {
  641.         sprintf(st, "%d", highscore);
  642.         c = st; 
  643.         x = 0.70;
  644.         while (*c) {
  645.         pushmatrix();
  646.         translate(x, -0.9, 0);
  647.         callobj(8000 + *c - '0');
  648.         popmatrix();
  649.         x+= 0.05;
  650.         c++;
  651.         }
  652.         
  653.     }
  654.     if (mouse_dead) {
  655.         /* draw the word 'dead' (obj 7000), scale it so it grows
  656.          * and in the end make it fade away, by increasing alpha
  657.          */
  658.         x = mouse_dead/20.0+0.2;
  659.         if (x > 1.7) {
  660.         x = 1.7;
  661.         }
  662.         if (mouse_dead > 40 ) { 
  663.         alph = (mouse_dead-40)/20.0;
  664.         set_alpha(alph);
  665.         }
  666.         translate(0,0.4,0);
  667.         /*rotate((x-0.2)/1.5 * 3600, 'z');*/
  668.         scale(x,x,x);
  669.         callobj(7000);
  670.         set_alpha(0);
  671.     }
  672.     popmatrix();
  673.     if (displmode == DMRGBDOUBLE )
  674.         swapbuffers();    /* Show what we just drew */
  675.     break;
  676.       default:
  677.     /* something is wrong, but call draw_whatever2d to handle it */
  678.     printf("WRONG\n");
  679.     draw_whatever2d();
  680.  
  681.     }
  682. }
  683.  
  684. void draw_whatever2d(void) {
  685.     IMAGE *image;
  686.     char tmpstr[256];
  687.     int i;
  688.     float v1[3];
  689.     
  690.     zbuffer(FALSE);
  691.     subpixel(TRUE);
  692.     if (displmode == DMRGBDOUBLE ) {
  693.     switch_single();
  694.     clear();
  695.     gflush();
  696.     }
  697.     pushmatrix();
  698.     ortho2(0,1,0,1);
  699.     bgnpolygon();
  700.     v1[0] = 0; v1[1] = 1; cpack(0x000022bb);
  701.     v2f(v1);
  702.     v1[1] = 0; cpack(0x000061ff);
  703.     v2f(v1);
  704.     v1[0] = 1; cpack(0x000052ff);
  705.     v2f(v1);
  706.     v1[1] = 1; cpack(0x000038ff);
  707.     v2f(v1);
  708.     endpolygon();
  709.     switch (display_scene) {
  710.       case SORRY:
  711.     getsize(&sizey, &sizey);
  712.     ortho2(0, sizex, 0, sizey);
  713.     set_fontcolor(0x0000A0A0, 0x00E0E0);
  714.     set_fontsize(0.075);
  715.     draw_stringXY(0.10, 0.9, "S O R R Y");
  716.     set_fontsize(0.060);
  717.     set_fontcolor(0x00b0b0, 0x00c0c0);
  718.     draw_stringXY(0.20, 0.72,
  719.         "For some reason Blix is\n"
  720.         "not able to connect to \n"
  721.         "the server that keeps\n"
  722.         "track of the highscores.\n\n\n"
  723.         "See the man page for\n"
  724.         "more details.");
  725.     gflush();
  726.     break;
  727.       case PAUSED:
  728.     strcpy(tmpstr, datadir);
  729.     strcat(tmpstr, "blixphoto.rgb");
  730.     image = iopen(tmpstr, "r");
  731.     if (image == NULL) {
  732.         fprintf(stderr,"%s: cannot locate photo image\n", basename);
  733.         exit_program();
  734.     }      
  735.     draw_image(image, 0.05, 0.25, 0.70, 0.90);
  736.     getsize(&sizey, &sizey);
  737.     ortho2(0, sizex, 0, sizey);
  738.     set_fontcolor(0x0000A0A0, 0x00E0E0);
  739.     set_fontsize(0.20);
  740.     draw_stringXY(0.21, 0.63, " Game\nPaused");
  741.     set_fontsize(0.05);
  742.     draw_stringXY(0.37, 0.05, "Click mouse to continue...");
  743.     gflush();
  744.     break;
  745.       case INTRO:
  746.     strcpy(tmpstr, datadir);
  747.     strcat(tmpstr, "blixrt.rgb");
  748.     image = iopen(tmpstr, "r");
  749.     if (image == NULL) {
  750.         fprintf(stderr,"%s: cannot locate intro image\n", basename);
  751.         if (no_sfx == 0 )
  752.         end_sound();
  753.         gexit();
  754.         exit(1);
  755.     }      
  756.     ortho2(0, 1, 0, 1);
  757.     draw_image(image, 0.05, 0.50, 0.05, 0.85);
  758.     iclose(image);
  759.     getsize(&sizey, &sizey);
  760.     ortho2(0, sizex, 0, sizey);
  761.     set_fontcolor(0x0000A0A0, 0x00E0E0);
  762.     set_fontsize(0.070);
  763.     draw_stringXY(0.60, 0.9, "WELCOME");
  764.     set_fontsize(0.050);
  765.     draw_stringXY(0.59, 0.82,
  766.         "My name is Blix.\n"
  767.         "I am the not too\n"
  768.         "undestructable\n"
  769.         "hero of this game.\n\n"
  770.         "Use the right\n"
  771.         "mousebutton to\n"
  772.         "popup the menu");
  773.     draw_stringXY(0.59, 0.26,
  774.         "Loading data...\n"
  775.         "Please wait.");
  776.     draw_stringXY(0.59, 0.13,
  777.         "Blix is written by\n"
  778.         "Frans van Hoesel\n");
  779.     zbuffer(zbuf);
  780.     gflush();
  781.     break;
  782.           
  783.      case PRIVATHIGH:
  784.     getsize(&sizex, &sizey);
  785.     inf = getinf();
  786.     ortho2(0, sizex, 0, sizey);
  787.     set_fontcolor(0x0000A0A0, 0x00E0E0);
  788.     set_fontsize(0.078);
  789.     draw_stringXY(0.05, 0.92, "Y");
  790.     draw_stringXY(0.076, 0.92, "our personal highscores:");
  791.     sprintf(tmpstr,"after %d runs", (int)privatlist.game);
  792.     set_fontsize(0.043);
  793.     draw_stringXY(0.35, 0.85, tmpstr);
  794.     for (i=0; i< 7; i++) {
  795.         set_fontcolor((7.0-i)*0x202203, (7-i)*0x242400);
  796.         draw_stringXY(0.65, 0.77 - i * 0.1, privatlist.names[i]);
  797.         set_fontcolor((11.0-i)*0x111213, (11-i)*0x131313);
  798.         draw_stringXY(0.56, 0.77 - i * 0.1, "pts");
  799.     }
  800.     set_fontsize(0.053);
  801.     for (i=0; i<7; i++) {
  802.         set_fontcolor((7-i)*0x202000, (7-i)*0x242400);
  803.         sprintf(tmpstr, "%d", (int)privatlist.scores[i]);
  804.         draw_stringXY(0.55 - (strlen(tmpstr)* 0.032), 0.77 - i * 0.1, tmpstr);
  805.     }
  806.     set_fontcolor(0x05122d, 0x08102D);
  807.     draw_stringXY(0.05, 0.105, inf->name);
  808.     draw_stringXY(0.05, 0.04, inf->host);
  809.     image = NULL;
  810.     if (inf->image != NULL && *(inf->image) != '\0')
  811.         image = iopen(inf->image, "r");
  812.     if (image == NULL) {
  813.         strcpy(tmpstr, datadir);
  814.         strcat(tmpstr, "noimage.rgb");
  815.         image = iopen(tmpstr, "r");
  816.     }
  817.     if (image != NULL) {
  818.         draw_image(image, 0.05, 0.35, 0.50, 0.80);
  819.         iclose(image);
  820.     }
  821.     gflush();
  822.     break;
  823.       case SYSTEMHIGH:
  824.     getsize(&sizex, &sizey);
  825.     ortho2(0, sizex, 0, sizey);
  826.     set_fontcolor(0x0000A0A0, 0x00E0E0);
  827.     set_fontsize(0.060);
  828.     draw_stringXY(0.04, 0.94, "The Best Players on your System:");
  829.     sprintf(tmpstr,"after %d runs", (int)systemlist.game);
  830.     set_fontsize(0.043);
  831.     draw_stringXY(0.35, 0.87, tmpstr);
  832.     for (i=0; i< 7; i++) {
  833.         set_fontcolor((7.0-i)*0x202203, (7-i)*0x242400);
  834.         if (systemlist.names[i] != NULL &&
  835.             *(systemlist.names[i]) != '\0') {
  836.         draw_stringXY(0.57, 0.74 - i * 0.1, systemlist.names[i]);
  837.         }
  838.         set_fontcolor(0x05122d, 0x08102D);
  839.         if (systemlist.hosts[i] != NULL &&
  840.             *(systemlist.hosts[i]) != '\0') {
  841.         strcpy(tmpstr,"(");
  842.         strcat(tmpstr, systemlist.hosts[i]);
  843.         strcat(tmpstr,")");
  844.         draw_stringXY(0.57, 0.69 - i * 0.1, tmpstr);
  845.         }
  846.         set_fontcolor((11.0-i)*0x111213, (11-i)*0x131313);
  847.         draw_stringXY(0.50, 0.74 - i * 0.1, "pts");
  848.     }
  849.     set_fontsize(0.053);
  850.     for (i=0; i<7; i++) {
  851.         set_fontcolor((7-i)*0x202000, (7-i)*0x242400);
  852.         sprintf(tmpstr, "%d", (int) systemlist.scores[i]);
  853.         draw_stringXY(0.49 - (strlen(tmpstr)* 0.032), 0.74 - i * 0.1, tmpstr);
  854.     }
  855.     for (i=0; i<7; i++) {
  856.         image = NULL;
  857.         if (systemlist.images[i] != NULL && *(systemlist.images[i]) != '\0')
  858.         image = iopen(systemlist.images[i], "r");
  859.         if (image == NULL) {
  860.         strcpy(tmpstr, datadir);
  861.         if (strncmp(systemlist.names[i], "Blix", 4) == NULL) {
  862.             strcat(tmpstr, "/blixphoto.rgb");
  863.         } else {
  864.             strcat(tmpstr, "/noimage.rgb");
  865.         }
  866.         image = iopen(tmpstr, "r");
  867.         }
  868.         if (image != NULL) {
  869.         draw_image(image,
  870.             0.18-(i&1)*0.16, 0.32-(i&1)*0.16, 0.683 - i*0.1, 0.823 - i*0.1);
  871.         iclose(image);
  872.         }
  873.     }
  874.     gflush();
  875.     break;
  876.       case WORLDHIGH:
  877.     getsize(&sizex, &sizey);
  878.     ortho2(0, sizex, 0, sizey);
  879.     set_fontcolor(0x0000A0A0, 0x00E0E0);
  880.     set_fontsize(0.060);
  881.     draw_stringXY(0.04, 0.94, "The Best Players of the World:");
  882.     sprintf(tmpstr,"after %d runs", (int) worldlist.game);
  883.     set_fontsize(0.043);
  884.     draw_stringXY(0.35, 0.87, tmpstr);
  885.     for (i=0; i< 7; i++) {
  886.         set_fontcolor((7.0-i)*0x202203, (7-i)*0x242400);
  887.         if (worldlist.names[i] != NULL &&
  888.             *(worldlist.names[i]) != '\0') {
  889.         draw_stringXY(0.57, 0.74 - i * 0.1, worldlist.names[i]);
  890.         }
  891.         set_fontcolor(0x05122d, 0x08102D);
  892.         if (worldlist.hosts[i] != NULL &&
  893.             *(worldlist.hosts[i]) != '\0') {
  894.         strcpy(tmpstr,"(");
  895.         strcat(tmpstr, worldlist.hosts[i]);
  896.         strcat(tmpstr,")");
  897.         draw_stringXY(0.57, 0.69 - i * 0.1, tmpstr);
  898.         }
  899.         set_fontcolor((11.0-i)*0x111213, (11-i)*0x131313);
  900.         draw_stringXY(0.50, 0.74 - i * 0.1, "pts");
  901.     }
  902.     set_fontsize(0.053);
  903.     for (i=0; i<7; i++) {
  904.         set_fontcolor((7-i)*0x202000, (7-i)*0x242400);
  905.         sprintf(tmpstr, "%d", (int) worldlist.scores[i]);
  906.         draw_stringXY(0.49 - (strlen(tmpstr)* 0.032), 0.74 - i * 0.1, tmpstr);
  907.     }
  908.     for (i=0; i<7; i++) {
  909.         image = NULL;
  910.         if (worldlist.images[i] != NULL && *(worldlist.images[i]) != '\0')
  911.         image = iopen(worldlist.images[i], "r");
  912.         if (image == NULL) {
  913.         strcpy(tmpstr, datadir);
  914.         if (strncmp(worldlist.names[i], "Blix", 4) == NULL) {
  915.             strcat(tmpstr, "/blixphoto.rgb");
  916.         } else {
  917.             strcat(tmpstr, "/noimage.rgb");
  918.         }
  919.         image = iopen(tmpstr, "r");
  920.         }
  921.         if (image != NULL) {
  922.         draw_image(image,
  923.             0.18-(i&1)*0.16, 0.32-(i&1)*0.16, 0.683 - i*0.1, 0.823 - i*0.1);
  924.         iclose(image);
  925.         }
  926.     }
  927.     gflush();
  928.     break;
  929.     }
  930.     popmatrix();
  931. }
  932.  
  933.  
  934. void reset_rot(void) {
  935.     rvec[0] = 0;
  936.     rvec[1] =0;
  937.     rvec[2] = 0;
  938.     rvec[3] = 1;
  939.     build_matrix();    
  940. }
  941.  
  942.  
  943. void build_matrix(void) {
  944.     build_rotmatrix(rotmat, rvec);
  945.     minvert(rotmat, invrotmat);
  946. }
  947.  
  948.  
  949. void reset_transforms(void) {
  950.     rvec[0] = rvec[1] = rvec[2] = 0.0;
  951.     rvec[3] = 1.0;
  952.     trans[0] = trans[1] = trans[2] = 0.0;
  953.     trans[2] = TRANS;
  954.     set_perspective();
  955.     build_matrix();
  956. }
  957.  
  958. void stop_spin(void) {
  959.     spinrot[0] = 0;
  960.     spinrot[1] = 0;
  961.     spinrot[2] = 0;
  962.     spinrot[3] = 1;
  963. }
  964.  
  965. void toggle_zbuf(void) {
  966.     zbuf =  !zbuf;
  967.     zbuffer(zbuf);
  968.     draw_whatever();
  969. }
  970.  
  971. void build_again(void) {
  972.     free_arcs();
  973.     init_maze();
  974.     build_maze(0, Lod);
  975.     draw_whatever();
  976. }
  977.  
  978.  
  979. void set_lod(int l) {
  980.     Lod = l-1;
  981.     free_arcs();
  982.     if (Lod >= EXTRA_LIGHT )
  983.     lmbind(LIGHT1,2);
  984.     else
  985.     lmbind(LIGHT1,0);
  986.     if (Lod >= EXTRA_FINE) {
  987.     sphmode(SPH_DEPTH, 12);
  988.     } else {
  989.     if (Lod >= WALLS_UP) {
  990.         sphmode(SPH_DEPTH, 10);
  991.     } else {
  992.         sphmode(SPH_DEPTH, 8);
  993.     }
  994.     }
  995.     shademodel(GOURAUD);
  996.     build_maze(0, Lod);
  997.     draw_whatever();
  998. }
  999.  
  1000. void toggle_report(void) {
  1001.     report_nodenum = !report_nodenum;
  1002. }
  1003.  
  1004.  
  1005. void set_perspective(void) {
  1006.  
  1007.     static float t = TRANS;
  1008.     float   val;
  1009.     
  1010.     if (t == trans[2])
  1011.     return;
  1012.     val = trans[2]*SCALE*TANFOVY;
  1013.     /*ortho(val, -val,
  1014.         val, -val, NEAR, 
  1015.         -trans[2] + EXTRA);*/
  1016.     y_pos = trans[1]/(-val);
  1017.     set_trackball(1.0/(-val), y_pos);
  1018.     t = trans[2];
  1019. }
  1020.  
  1021.  
  1022.  
  1023. /*_________________________________________________________________________
  1024.  |
  1025.  | init_windows - initalize gl window
  1026.  |
  1027. */
  1028.  
  1029. void init_windows(void) {
  1030.     
  1031.     foreground();
  1032.     if (getgdesc(GD_BITS_NORM_DBL_RED) == 0 ||
  1033.         getgdesc(GD_BITS_NORM_DBL_GREEN) == 0 ||
  1034.         getgdesc(GD_BITS_NORM_DBL_BLUE) == 0) {
  1035.     fprintf(stderr, "Blix requires RGB mode which is not "
  1036.         "supported on your machine\n");
  1037.     exit (1);
  1038.     }
  1039.     if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0) {
  1040.     fprintf(stderr, "Blix requires a zbuffer which is not "
  1041.         "supported on your machine\n");
  1042.     exit(1);
  1043.     }
  1044.     if (getgdesc(GD_SCRNTYPE) == GD_SCRNTYPE_NOWM) {
  1045.         prefposition(0, getgdesc(GD_YPMAX)/3-1,
  1046.                      0, getgdesc(GD_YPMAX)/3-1);
  1047.     } 
  1048.     minsize(300,300);
  1049.     winopen("blix");
  1050.     wintitle("blix (demo only)");
  1051.     icontitle("blix");
  1052.     keepaspect(1,1);
  1053.     minsize(100,100);
  1054.     winconstraints();
  1055.     RGBmode();
  1056.     displmode = DMRGBDOUBLE;
  1057.     doublebuffer();
  1058.     gconfig();
  1059.     chunksize(508);
  1060.     gflush();
  1061.     mmode(MVIEWING);
  1062.     zbuffer(TRUE);
  1063.     zmin = getgdesc(GD_ZMIN) & 0xffffff00;
  1064.     zmax = getgdesc(GD_ZMAX) & 0xffffff00;
  1065.     lsetdepth(zmin, zmax);
  1066.     cpack(0x00000000);
  1067.     czclear(0x00000000, zmax);
  1068.     subpixel(TRUE);
  1069.     can_do_textures = getgdesc(GD_TEXTURE);
  1070. }
  1071.  
  1072.